//TODO: Define the function for mount
#include "common_headers.h"

void mountvfs31(char vfs_label[50])
{
	//DECLARATIONS:
	int i, y, is_mounted, is_mounting_file_exist, is_valid_file_vfs_label;
	struct FileDescriptor *fd_Desc1, *fdd;
	FILE *fptr1=NULL;
	
	//INITIALIZATIONS:
	is_mounted = 0;
	is_mounting_file_exist = 0;
	is_valid_file_vfs_label = 0;

	//CHECK IF VFS MOUNTED
	is_mounted = validateMountState();
	if(is_mounted==0)
	{
		//CHECK IF THE VFS FILE WE ARE MOUNTING NOW EXISTS
		is_mounting_file_exist = validateMountingFileExistance(vfs_label);		
		if(is_mounting_file_exist)
		{
			//CHECK IF THE FILE NAME WE ARE MOUNTING NOW IS VALID
			is_valid_file_vfs_label = validateMountingFileName(vfs_label);
			if(is_valid_file_vfs_label)
			{			
				fptr1=fopen(vfs_label,"rb+");			 
				if(fptr1!=NULL)
				{
					fread(&mainHeader,sizeof(struct MainHeader),1,fptr1);
					
					//FREE LIST INITIALIZED
					freelist=(char *)malloc(mainHeader.maximumFileDescriptor*sizeof(char));
					fread(freelist,(mainHeader.maximumFileDescriptor*sizeof(char)),1,fptr1);
					
					//FILE DESCRIPTOR INITIALIZED; READING THE CONTENTS OF THE VFS FILE INTO THE FILE DESCRIPTOR
					fileDescriptors=(struct FileDescriptor *)malloc(mainHeader.maximumFileDescriptor*sizeof(struct FileDescriptor));
					fread(fileDescriptors,(mainHeader.maximumFileDescriptor*sizeof(struct FileDescriptor)),1,fptr1);
					fclose(fptr1);
					
					//READING FROM FILE THAT IS MOUNTED, AND INSERTING INTO FILE DESCRIPTOR
					fdd=(struct FileDescriptor *)malloc(sizeof(struct FileDescriptor));
		 		    strcpy(fdd->locationpath,"/");
		 		    strcpy(fdd->filename,"/");
		 		    strcpy(fdd->filetype,"root");
		 		    fdd->locationblocknumber=-1;
					fdd->filesize=0;
			
					//INITIALIZING DATASTRUCTURES WITH ROOT
					y=naryRoot(fdd);			//N-ARY
					hash_initialize(ht_start);	//HASH-TABLE
					initialize_BST();			//BST
											
					//INITIALIZING DATASTRUCTURES WITH DATA IN FILE THAT IS MOUNTED NOW
					for(i=0; i < (mainHeader.maximumFileDescriptor); i++)
					{				
						if(freelist[i]!=0)
						{		    
							//INSERTION INTO N-ARY, HASH-TABLE, BST ; FOR EVERY FILE DESCRIPTOR
						    fd_Desc1=&fileDescriptors[i];					        
		
						    insert2(fd_Desc1);							//N-ARY INSERTION								        
		                    ht_start= hash_insert(ht_start, vfs_label);	//HASH-TABLE INSERTION						        			
						    BSTInsert(fd_Desc1);						//BST INSERTION
						}				
					}
					
					//MOUNTED SUCCESSFULLY, AND HENCE UPDATING THE GLOBAL VARIABLE "mountstate"
					mountstate=1;
					printf("mountvfs_SUCCESS\n");	   				
				}
				else
				{
					//CANNOT_READ_FROM_FILE
					printf("mountvfs_FAILURE %s\n", ERR_VFS_MOUNT_02);
				}			
			}
			else
			{
				//INVALID_CHARACTER_IN_NAME
				printf("mountvfs_FAILURE %s\n", ERR_VFS_MOUNT_05); //To be added
			}
		}
		else
		{
			//DATA_FILE_NOT_FOUND
				printf("mountvfs_FAILURE %s\n", ERR_VFS_MOUNT_01);
		}	
	}
	else
	{
		//VFS_ALREADY_MOUNTED
		printf("mountvfs_FAILURE %s\n", ERR_VFS_MOUNT_04);			
	}
}


//------------------------------------------------------------------------------

//used for insering into n-ary tree during mount operation
int insert2(struct FileDescriptor *fd_Desc1)
{
	//DECLARATIONS AND INTIALIZATIONS:
    char dir[300];
    int q=0,j=0,y=0;
    
    dir[q]=fd_Desc1->locationpath[q];
    q++;
    while( q < strlen(fd_Desc1->locationpath) )
    {
        while(fd_Desc1->locationpath[q]!='/' && q<strlen(fd_Desc1->locationpath))
        {
            dir[q]=fd_Desc1->locationpath[q];
            q++;
        }
        dir[q]='\0';
		
		//SEARCH N-ARY
        y=search_nary(dir);
        if(y==0)
        {
            if(q==strlen(fd_Desc1->locationpath))
            {
				//N-ARY INSERTION
                j=insert_nary(fd_Desc1);

            }
            else
            {
            	//CREATING A FILE DESCRIPTOR
                struct FileDescriptor *fd_Desc11;
                fd_Desc11=(struct FileDescriptor *)malloc(sizeof(struct FileDescriptor));
                strcpy(fd_Desc11->locationpath,dir);
                strcpy(fd_Desc11->filetype,"dummy");
                j=insert_nary(fd_Desc11);
            }
        }
        else if(y==1 && q==strlen(fd_Desc1->locationpath))
        {
			//UPDATE N-ARY
            update_nary(fd_Desc1);
        }
        if(fd_Desc1->locationpath[q]=='/')
        {
            dir[q]=fd_Desc1->locationpath[q];
            q++;
        }
    }

    if(j==1 || y==1)
    {
    	return 1;
    }
    else
    {
    	return 0;
    }
}

